Advertisement
Guest User

Untitled

a guest
May 13th, 2018
4
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.09 KB | None | 0 0
  1. #define __assume(c) { if (!(c)) { __builtin_unreachable(); } }
  2.  
  3. template <typename T> using arg_t = const T & __restrict;
  4.  
  5. template <typename F>
  6. static constexpr void validate_type ()
  7. {
  8.     using traits = float_traits<F>;
  9.     static_assert((traits::significand_bits + traits::exponent_bits + 1) == (sizeof(traits) * 8), "floating-point format mismatch");
  10.     static_assert(traits::significand_offset == 0, "floating-point format assumption error");
  11.     static_assert(traits::exponent_offset == traits::significand_bits, "floating-point format assumption error");
  12.     static_assert(traits::sign_offset == (traits::significand_bits + traits::exponent_bits), "floating-point format assumption error");
  13. }
  14.  
  15. template <typename Fout, typename Fin>
  16. Fout convert_to (Fin in) __attribute__ ((const, pure, flatten))
  17. {
  18.     if constexpr (std::is_same_v<Fout, Fin>)
  19.     {
  20.         return in;
  21.     }
  22.     using Tout = float_traits<Fout>;
  23.     using Tin = float_traits<Fin>;
  24.     validate_type<Fout>();
  25.     validate_type<Fin>();      
  26.     using uint_out = uintb<sizeof(Fout)>;
  27.     using uint_in = uintb<sizeof(Fin)>;
  28.     static_assert(sizeof(uint_out) == sizeof(Fout), "uint_out / Fout size mismatch");
  29.     static_assert(sizeof(uint_in) == sizeof(Fin), "uint_in / Fin size mismatch");
  30.    
  31.     union in_union_t
  32.     {
  33.         const Fin value_;
  34.         struct data
  35.         {
  36.             uint_in significand : Tin::significand_bits;
  37.             uint_in exponent : Tin::exponent_bits;
  38.             uint_in sign : 1;
  39.         } const data_;
  40.    
  41.         in_union_t (arg_t<Fin> val) : value_(val) {}
  42.     } const in_expand = {in};
  43.    
  44.     union out_union_t
  45.     {
  46.         const Fout value_;
  47.         struct data
  48.         {
  49.             uint_out significand : Tout::significand_bits;
  50.             uint_out exponent : Tout::exponent_bits;
  51.             uint_out sign : 1;
  52.            
  53.             data (arg_t<in_union_t> in) :
  54.                 significand(({ __assume(in.data_.significand < bit_val<Tin::significand_bits>); in.data_.significand; })),
  55.                 exponent(({ __assume(in.data_.exponent < bit_val<Tin::exponent_bits>); in.data_.exponent; })),
  56.                 sign(({ __assume(in.data_.sign <= 1); in.data_.sign; }))
  57.             {}
  58.         } const data_;
  59.    
  60.         out_union_t (arg_t<in_union_t> in) : data_(in) {}
  61.     };
  62.    
  63.     return out_union_t{in_expand}.value_;
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement